package org.itboys.mobile.service.mysql.weixin.order;

import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.time.TimeUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.order.CooOrderProductMapper;
import org.itboys.mobile.dto.count.SundayCountDto;
import org.itboys.mobile.dto.count.SundayCountProductDto;
import org.itboys.mobile.dto.order.CooOrderDto;
import org.itboys.mobile.dto.order.CooOrderProductDto;
import org.itboys.mobile.entity.mongo.SundayAddress;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.order.CooOrder;
import org.itboys.mobile.entity.mysql.order.CooOrderProduct;
import org.itboys.mobile.entity.mysql.product.SundayProduct;
import org.itboys.mobile.service.mongo.web.member.SundayMemberService;
import org.itboys.mobile.service.mongo.weixin.address.SundayWeixinAddressService;
import org.itboys.mobile.service.mongo.weixin.cart.CooWeixinCartService;
import org.itboys.mobile.service.mongo.weixin.comment.CooWeixinCommentService;
import org.itboys.mobile.service.mongo.weixin.count.CooWeixinCountService;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mongodb.service.BaseMySqlService;
import org.itboys.param.ParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 作者：zzq
 * 时间：2017/12/7
 * 描述：迈迪龙_微信_订单
 */
@Service
public class CooWeixinOrderService extends BaseMySqlService<CooOrder>{
    @Autowired
    private SundayWeixinAddressService addressService;
    @Autowired
    private CooWeixinCountService countService;
    @Autowired
    private CooOrderProductMapper orderProductMapper;
    @Autowired
    private CooWeixinCartService cartService;
    @Autowired
    private SundayMemberService memberService;
    @Autowired
    private CooWeixinCommentService commentService;
    @Transactional
    public synchronized Map<String,Object> createOrder(Long memberId, Long productId, Long addressId,String remark){
        /**
         * 准备返回结果
         */
        Map<String,Object> result = new HashMap<String,Object>();

        BigDecimal payAmount = new BigDecimal(0);
        Integer isNeedToPay = SundayCommonConstants.YES;
        String orderIds ="";
        /**
         * 准备结算数据
         */
        if(!LongUtil.isNotZreo(addressId)){
            throw new ErrorException("请填写收货地址");
        }
        List<Long> productIds =new ArrayList<Long>();
        productIds.add(productId);
        List<Integer> numbers =new ArrayList<Integer>();
        numbers.add(1);
        List<Long> cartIds= cartService.addCart(memberId,productIds ,numbers, SundayCommonConstants.cart_type_buy_now);

        SundayCountDto countDto =countService.countCart(  memberId,cartIds,null, addressId);
        SundayAddress address =addressService.getById(addressId);
        /**
         * 准备订单数据
         */
        CooOrder order = new CooOrder();
        order.setOrderNo(NumberUtil.generateNumber());
        order.setType(countDto.getType());
        order.setRemark(remark);
        order.setTotalAmount(countDto.getTotalAmount());
        order.setPayAmount(countDto.getPayAmount());
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);
        order.setReceiveName(address.getReceiveName());
        order.setReceiveMobile(address.getReceiveMobile());
        order.setReceiveAddress(address.getCityName()+address.getDistrictName()+address.getReceiveAddress());

        order.setMemberName(memberService.getById(memberId).getNickName());
        order.setMemberId(memberId);
        //保存订单
        super.insert(order);
        //2017年6月8日，保存订单商品（同时保存商品的拿货和出货折扣，分类ID）
        for(SundayCountProductDto productDto:countDto.getProducts()){

            CooOrderProduct orderProduct =

                    new CooOrderProduct(order.getId(),productDto.getId(),
                            productDto.getPrice(),productDto.getName(),productDto.getNumber(),
                            productDto.getImage(),
                            productDto.getStandard(),productDto.getNum(), productDto.getType());
            orderProductMapper.insert(orderProduct);
        }
        //删除购物车

        if(ListUtil.isNotNull(cartIds)){
            Map<String,Object> param= new HashMap<String, Object>();
            param.put("id in", cartIds);
            cartService.delete(param);
        }
        //返回数据
        orderIds=order.getId().toString();
        payAmount=order.getPayAmount();
        result.put("payAmount", payAmount.toString());
        result.put("isNeedToPay", isNeedToPay);
        result.put("orderIds", orderIds);
        result.put("msg", "");

        return result;
    }
    /**
     * 取消订单
     * @param orderId
     * @return
     */
    public void cancelOrder(Long orderId){

        CooOrder order= super.find(orderId);
        //用户的商城订单，待付款允许取消
        String msg=null;
        if(order.getType()==SundayCommonConstants.type_mall&&order.getOrderStatus()!=SundayCommonConstants.ORDER_STATUS_DFK){
            msg="非待付款订单，不能取消";
        }
        if(StringUtils.isNotEmpty(msg)){
            throw new ErrorException(msg);
        }
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YQX);
        super.update(order);
    }
    /**
     * 分页获取订单
     * @param request
     * @param memberId
     * @param orderStatus
     * @return
     */
    public List<CooOrderDto> selectOrder(HttpServletRequest request, Long memberId,  Integer orderStatus){
        Map<String,Object> param = ParamUtil.packageMysqlPageParam(request, "orderNo","sellerName","createTimeStart","createTimeEnd");
        SundayMember member = memberService.getById(memberId);
        param.put("memberId", memberId);
        //订单状态
        List<Integer> orderStatuses = new ArrayList<Integer>();
        //全部查询
        if(orderStatus==0){
            for(int i=1;i<=11;i++){

                orderStatuses.add(i);
            }
        }else{
            orderStatuses.add(orderStatus);
        }
        param.put("orderStatuses", orderStatuses);
        List<CooOrder> orders = super.select(param);
        List<CooOrderDto> dtos=changeToDto(orders);
        return dtos;
    }

    private List<CooOrderDto> changeToDto(List<CooOrder> orders){
        List<CooOrderDto> dtos = new ArrayList<CooOrderDto>();
        List<Long> orderIds = new ArrayList<Long>();
        Map<String,Object> param = new HashMap<String, Object>();
        for(CooOrder order:orders){
            orderIds.add(order.getId());
        }
        param.put("orderIds", orderIds);
        List<CooOrderProduct> orderProducts = orderProductMapper.select(param);

        for(CooOrder order:orders){
            CooOrderDto dto=new CooOrderDto();
            dto.setId(order.getId());
            dto.setOrderNo(order.getOrderNo());
            dto.setTotalAmount(order.getTotalAmount());
            dto.setPayAmount(order.getPayAmount());
            dto.setPayNo(order.getPayNo());
            dto.setOrderStatus(order.getOrderStatus());
            dto.setReceiveAddress(order.getReceiveAddress());
            dto.setRemark(order.getRemark());
            if(ListUtil.isNotNull(orderProducts)){
                for(CooOrderProduct orderProduct:orderProducts){
                    if(orderProduct.getOrderId().longValue()==order.getId().longValue()){
                        dto.setProductName(orderProduct.getName());
                        dto.setProductNum(orderProduct.getNum());
                        dto.setProductPrice(orderProduct.getPrice());
                        break;
                    }
                }

            }
            dtos.add(dto);
        }
        return dtos;
    }

    /**
     * 查询订单详情
     * @param orderId
     * @param memberId
     * @return
     */
    public CooOrderDto findOne(Long orderId, Long memberId){
        return pakageDtoSingle(super.find(orderId),null);
    }

    /**
     * 评论订单
     * @param orderId
     * @param productIds
     * @param contents
     * @param scores
     * @param images 图片集合，固定大小=productIds集合大小*3。。每个商品限制最大传入三张，没有图片的使用noImage字符传固定值。
     * @param memberId
     */
    public void  commentOrder(Long orderId,List<Long> productIds,List<String> contents,List<Integer> scores,List<String> images,Long memberId){
        String msg ="";
        if(ListUtil.isNull(productIds)||ListUtil.isNull(contents)||ListUtil.isNull(scores)){
            msg="评论接口参数有错误(为空)";
        }
        if(productIds.size()!=contents.size()||productIds.size()!=scores.size()||contents.size()!=scores.size()){
            msg="评论接口参数有错误（参数不对应）";
        }
        if(productIds.size()*3!=images.size()){
            msg="评论接口参数有错误（图片参数）";
        }
        if(msg!=""){
            throw new ErrorException(msg);
        }


        CooOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_YSH,"非待评论订单，不能评论",memberId);
        SundayMember member = memberService.getById(memberId);
        commentService.generateComment(productIds,
                contents,
                scores,
                images,
                memberId,
                member.getImage(),
                member.getNickName(),
                SundayProduct.class.getSimpleName());

        //更改订单状态
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YPJ);
        super.update(order);

    }
    /**
     * 确认收货
     * @param orderId
     * @param memberId
     * @return
     */
    @Transactional
    public void confirmReceive(Long orderId,Long memberId){


        CooOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_PSZ,"非配送中订单，不能确认收货",memberId);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YSH);
        order.setReceiveTime(new Date());

        //生成收益，
        //生成用户赠送积分(实付款+余额抵扣)
       /* if(order.getType()==SundayCommonConstants.type_mall){
            //SundayScoreConfig scoreConfig =scoreConfigService.findOne(null);
            BigDecimal thisAmount = order.getPayAmount();
            if(order.getBalancePayAmount()!=null){
                thisAmount.add(order.getBalancePayAmount());
            }
            memberService.changeScore(order.getOrderNo(),thisAmount, SundayCommonConstants.SCORE_TYPE_REWARD,memberId);
        }*/
        super.update(order);
    }
    /**
     * 校验订单信息
     * @param orderId
     * @param status
     * @param msg
     * @param memberId
     * @return
     */
    public CooOrder checkOrder(Long orderId, Integer status, String msg, Long memberId){
        CooOrder order =super.find(orderId);
        if(status!=null&&order.getOrderStatus()!=status){
            throw new ErrorException(msg);
        }
        if(LongUtil.isNotZreo(memberId)&&order.getMemberId().longValue()!=memberId){
            throw new ErrorException("数据错误，请重试");
        }
        return order;
    }
    /**
     * 组装DTO
     * @param order
     * @return
     */
    public CooOrderDto pakageDtoSingle(CooOrder order, List<CooOrderProductDto> products){
        if(ListUtil.isNull(products)){
            Map<String,Object> param =new HashMap<String ,Object>();
            param.put("orderId",order.getId());
            products=new ArrayList<CooOrderProductDto>();
            for(CooOrderProduct orderProduct:orderProductMapper.select(param)){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    products.add(new CooOrderProductDto(
                            orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }

        }
        String payTime= order.getPayTime()!=null? TimeUtils.format(order.getPayTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String sendTime= order.getSendTime()!=null?TimeUtils.format(order.getSendTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String receiveTime= order.getReceiveTime()!=null?TimeUtils.format(order.getReceiveTime(),"yyyy-MM-dd HH:mm:ss"):null;
        return new CooOrderDto(order.getId(),order.getCreateTime(),order.getCreateDate(),
                order.getOrderNo(), order.getType(), order.getTotalAmount(), order.getPayAmount(),
                order.getPayNo(), order.getOrderStatus(), order.getReceiveName(),order.getReceiveMobile(), order.getReceiveAddress(),
                order.getSendAmount(),order.getRemark(),
                payTime,sendTime, receiveTime,  products);

    }

    /**
     * 组装多个
     * @param orders
     * @return
     */
    public List<CooOrderDto> pakageDtoMuilt(List<CooOrder> orders){
        List<CooOrderDto> dtos= new ArrayList<CooOrderDto>();
        List<Long> orderIds = new ArrayList<>();
        for(CooOrder order:orders){
            orderIds.add(order.getId());
        }
        Map<String,Object> param =new HashMap<String ,Object>();
        param.put("orderIds",orderIds);
        List<CooOrderProduct> orderProducts = orderProductMapper.select(param);
        for(CooOrder order:orders){
            List<CooOrderProductDto> ps = new ArrayList<CooOrderProductDto>();
            for(CooOrderProduct orderProduct:orderProducts){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    ps.add(new CooOrderProductDto(orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }
            dtos.add(pakageDtoSingle(order,ps));
        }
        return dtos;
    }


}
